package ecoll.client.centers;

import java.util.ArrayList;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.datepicker.client.DateBox;

import ecoll.client.Client;
import ecoll.client.database.ProfileData;

public class PersonalDataCenter implements Center {

	private Function viewProfile = new Function() {
		@Override
		public void execute() {

			Client.DATABASE_SERVICE.getProfileData(
					Client.LOGIN_INFO.getNickname(),
					new AsyncCallback<ProfileData>() {

						@Override
						public void onFailure(Throwable e) {
							Window.alert("ProfileData fetching failure: "
									+ e.getMessage());
						}

						@Override
						public void onSuccess(ProfileData profileData) {
							displayProfile(profileData, false);
						}
					});
		}

		@Override
		public String name() {
			return "View my profile";
		}

	};

	private Function editProfile = new Function() {
		@Override
		public void execute() {
			Client.DATABASE_SERVICE.getProfileData(
					Client.LOGIN_INFO.getNickname(),
					new AsyncCallback<ProfileData>() {

						@Override
						public void onFailure(Throwable e) {
							Window.alert("ProfileData fetching failure: "
									+ e.getMessage());
						}

						@Override
						public void onSuccess(ProfileData profileData) {
							displayProfile(profileData, true);
						}
					});
		}

		@Override
		public String name() {
			return "Edit my profile";
		}

	};

	private Function findUsers = new Function() {
		@Override
		public void execute() {

			Grid profilePanel = new Grid(6, 2);
			profilePanel.getColumnFormatter().setStyleName(0, "labelColumn");

			profilePanel.setText(0, 0, "Login:");
			final TextBox loginBox = new TextBox();
			loginBox.setMaxLength(50);
			loginBox.setStyleName("inputBox");
			profilePanel.setWidget(0, 1, loginBox);

			profilePanel.setText(1, 0, "First name:");
			final TextBox firstNameBox = new TextBox();
			firstNameBox.setMaxLength(50);
			firstNameBox.setStyleName("inputBox");
			profilePanel.setWidget(1, 1, firstNameBox);

			profilePanel.setText(2, 0, "Last name:");
			final TextBox lastNameBox = new TextBox();
			lastNameBox.setMaxLength(100);
			lastNameBox.setStyleName("inputBox");
			profilePanel.setWidget(2, 1, lastNameBox);

			profilePanel.setText(3, 0, "E-mail:");
			final TextBox mailBox = new TextBox();
			mailBox.setMaxLength(100);
			mailBox.setStyleName("inputBox");
			profilePanel.setWidget(3, 1, mailBox);

			profilePanel.setText(4, 0, "Birth date:");
			final DateBox birthDateBox = new DateBox();
			birthDateBox.setFormat(new DateBox.DefaultFormat(DateTimeFormat
					.getShortDateFormat()));
			profilePanel.setWidget(4, 1, birthDateBox);

			Button findButton = new Button("Find");
			findButton.addClickHandler(new ClickHandler() {

				@Override
				public void onClick(ClickEvent event) {

					ProfileData data = new ProfileData();
					if (loginBox.getText().length() > 0)
						data.setLogin(loginBox.getText());
					if (firstNameBox.getText().length() > 0)
						data.setFirstName(firstNameBox.getText());
					if (lastNameBox.getText().length() > 0)
						data.setLastName(lastNameBox.getText());
					if (mailBox.getText().length() > 0)
						data.setMail(mailBox.getText());
					data.setBirthDate(birthDateBox.getValue());

					Client.DATABASE_SERVICE.findProfileData(data,
							new AsyncCallback<ArrayList<ProfileData>>() {

								@Override
								public void onFailure(Throwable e) {
									Window.alert("ProfileData fetching failure: "
											+ e.getMessage());
								}

								@Override
								public void onSuccess(
										ArrayList<ProfileData> profiles) {
									if (profiles.size() == 0)
										Window.alert("No match found!");
									else
										// if(profiles.size() == 1)
										displayProfile(profiles.get(0), false);
								}

							});
				}
			});
			profilePanel.setWidget(5, 0, findButton);
			Client.updateDashboard(profilePanel);
			profilePanel.addStyleName("profilePanel");
		}

		@Override
		public String name() {
			return "Find other users";
		}

	};

	@Override
	public String name() {
		return "Personal Data";
	}

	@Override
	public void execute() {
	}

	@Override
	public Function function(int i) {
		if (i < 0 || i > FUNCTION.length)
			return null;
		return FUNCTION[i];
	}

	private final Function[] FUNCTION = new Function[] { viewProfile,
			editProfile, findUsers };

	private void displayProfile(final ProfileData data, boolean editable) {

		Grid profilePanel = new Grid(7, 2);
		profilePanel.getColumnFormatter().setStyleName(0, "labelColumn");

		HTML userLabel = new HTML("<h3>" + data.getLogin() + "</h3>");
		profilePanel.setWidget(0, 0, userLabel);

		profilePanel.setText(1, 0, "First name:");
		final TextBox firstNameBox = new TextBox();
		firstNameBox.setText(data.getFirstName());
		firstNameBox.setMaxLength(50);
		firstNameBox.setEnabled(editable);
		firstNameBox.setStyleName("inputBox");
		profilePanel.setWidget(1, 1, firstNameBox);

		profilePanel.setText(2, 0, "Last name:");
		final TextBox lastNameBox = new TextBox();
		lastNameBox.setText(data.getLastName());
		lastNameBox.setMaxLength(100);
		lastNameBox.setEnabled(editable);
		lastNameBox.setStyleName("inputBox");
		profilePanel.setWidget(2, 1, lastNameBox);

		profilePanel.setText(3, 0, "E-mail:");
		final TextBox mailBox = new TextBox();
		mailBox.setText(data.getMail());
		mailBox.setMaxLength(100);
		mailBox.setEnabled(editable);
		mailBox.setStyleName("inputBox");
		profilePanel.setWidget(3, 1, mailBox);

		profilePanel.setText(4, 0, "Birth date:");
		final DateBox birthDateBox = new DateBox();
		if (data.getBirthDate() != null)
			birthDateBox.setValue(data.getBirthDate());
		birthDateBox.setFormat(new DateBox.DefaultFormat(DateTimeFormat
				.getShortDateFormat()));
		birthDateBox.setEnabled(editable);
		profilePanel.setWidget(4, 1, birthDateBox);

		profilePanel.setText(5, 0, "Description:");
		final TextArea descriptionBox = new TextArea();
		descriptionBox.setText(data.getDescription());
		descriptionBox.setEnabled(editable);
		descriptionBox.setStyleName("descriptionBox");
		profilePanel.setWidget(5, 1, descriptionBox);

		if (Client.LOGIN_INFO.getNickname().equals(data.getLogin())) {
			if (editable) {
				Button saveButton = new Button("Save");

				saveButton.addClickHandler(new ClickHandler() {

					@Override
					public void onClick(ClickEvent event) {
						if (!mailBox.getText().equals(data.getMail())) {
							Window.alert("E-mail change not supported yet!");
							mailBox.setText(data.getMail());
							return;
						}
						if (birthDateBox.getValue() == null) {
							birthDateBox.setValue(null);
						}
						if (descriptionBox.getText().length() > 400) {
							Window.alert("Maximum length of the description is 400 characters!!");
							return;
						}
						data.setFirstName(firstNameBox.getText());
						data.setLastName(lastNameBox.getText());
						data.setMail(mailBox.getText());
						data.setBirthDate(birthDateBox.getValue());
						data.setDescription(descriptionBox.getText());
						Client.DATABASE_SERVICE.updateProfileData(data,
								new AsyncCallback<Void>() {

									@Override
									public void onFailure(Throwable e) {
										Window.alert("ProfileData fetching failure: "
												+ e.getMessage());
									}

									@Override
									public void onSuccess(Void result) {
										Window.alert("Data successfully saved!");
										viewProfile.execute();
									}

								});
					}

				});
				profilePanel.setWidget(6, 0, saveButton);
			} else {
				Button editButton = new Button("Edit");

				editButton.addClickHandler(new ClickHandler() {

					@Override
					public void onClick(ClickEvent event) {
						displayProfile(data, true);
					}

				});
				profilePanel.setWidget(6, 0, editButton);
			}
		}
		Client.updateDashboard(profilePanel);
		profilePanel.addStyleName("profilePanel");
	}
}
